package org.example;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.time.LocalDate;
import java.util.Objects;

public class Certificate {
    private final String serialNumber;
    private final LocalDate expireDate;
    private final String organization;
    private final String domainName;
    private final PublicKey publicKey;
    private final String issuer;
    private byte[] sign;

    private volatile boolean valid;

    public Certificate(String serialNumber, LocalDate expireDate, String organization, String domainName, PublicKey publicKey, String issuer) {
        this.serialNumber = serialNumber;
        this.expireDate = expireDate;
        this.organization = organization;
        this.domainName = domainName;
        this.publicKey = publicKey;
        this.issuer = issuer;
    }

    /**
     * 计算证书摘要
     */
    public String calDigest() {
        return md5(serialNumber + expireDate + organization + domainName + publicKey + issuer);
    }

    /**
     * 校验签名
     * @param decryptSign
     */
    public void validateSign(String decryptSign) {
        if (!Objects.equals(calDigest(), decryptSign)) {
            throw new RuntimeException("证书校验签名错误");
        }
    }

    public PublicKey getPublicKey() {
        return publicKey;
    }

    public byte[] getSign() {
        return sign;
    }

    public void setSign(byte[] sign) {
        this.sign = sign;
    }

    public boolean isValid() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    private String md5(String msg) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(msg.getBytes(StandardCharsets.UTF_8));
            // messageDigest.digest()返回一个整数，用byte数组表示，需要先转为整数BigInteger再转为16进制显示
            return new BigInteger(1, messageDigest.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("算法配置错误", e);
        }
    }

    @Override
    public String toString() {
        return "Certificate{" +
                "serialNumber='" + serialNumber + '\'' +
                ", expireDate=" + expireDate +
                ", organization='" + organization + '\'' +
                ", domainName='" + domainName + '\'' +
                ", publicKey=" + publicKey +
                ", issuer='" + issuer + '\'' +
                ", sign='" + sign + '\'' +
                '}';
    }

    public static void main(String[] args) {
    }
}
